#ifndef __SUBCTRL_H__
#define __SUBCTRL_H__

#include "main.h"
#include "pid.h"
#include "stream.h"

#define TARGET_POWER_MAX 1500
#define FORWARD_ERROR_THRESHOLD 500.0f
#define REVERSE_ERROR_THRESHOLD 120.0f
#define TIM_AUTORELOAD 1000
#define ATTENUATION_STEP 0.1f
#define ATTENUATION_MAX 30.0f
#define PHASE_STEP 1.4f
#define PHASE_MAX 358.6f
#define PHASE_DIR_ANTI_COUNT 10
#define FORWARD_PID_KP_MAX 0.05f
#define FORWARD_PID_KI_MAX 0.001f
#define FORWARD_PID_KD_MAX 0.001f
#define FORWARD_PID_OUTPUT_MAX 5.0f
#define REVERSE_PID_KP_MAX 0.05f
#define REVERSE_PID_KI_MAX 0.001f
#define REVERSE_PID_KD_MAX 0.001f
#define REVERSE_PID_OUTPUT_MAX 10.0f

class SubController
{
  public:
    SubController(sub_control_t &handle, const pa_module_hardware_config_t (&config)[kModuleNum])
        : handle_(handle), config_(config) {};
    ~SubController() {};
    void Init(StreamProcessor *log);
    void OutputEnable();
    void OutputEnable(pa_module_id_t &id);
    void OutputDisable();
    void OutputDisable(pa_module_id_t &id);
    void ForwardLoop();
    void ReverseLoop();

    void SetTargetPower(int value);
    void SetAttenuation(const pa_module_id_t &id, const float &dB);
    void SetAttenuation(float pa1_dB, float pa2_dB, float pa3_dB);
    void SetAttenuation(uint8_t bit, const int dB_step);
    void SetAttenuation(float dB[kModuleNum]);
    void SetPhase(const pa_module_id_t &id, const float &deg);
    void SetPhase(float pa1_deg, float pa2_deg, float pa3_deg);
    void SetPhase(uint8_t bit, const int deg_step);
    void SetPhase(float deg[kModuleNum]);
    void SetAddress(uint8_t *addr);
    void SetAutoRun(switch_state_t &state);
    void SetForwardPID(pid_config_t &config);
    void SetReversePID(pid_config_t &config);
    void PrintPidParam(pid_t &pid);
    void SaveParameter();
    void LoadParameter();
    void ResetParameter();
    sub_control_id_t GetDeviceID();
    char *GetStatus();
    uint8_t CheckAddress(uint8_t &addr);
    /**
     * @brief 重启子控制器
     * @note mode == 1: 模拟硬件重启; mode != 1: 软件重启
     * @param mode
     */
    void Restart(uint8_t &mode);

  private:
    const pa_module_hardware_config_t (&config_)[kModuleNum];
    sub_control_t &handle_;
    StreamProcessor *LOG;
    pid_t forward_pid_;
    pid_t reverse_pid_;
    sub_control_flash_t flash_;

    void OutputBitCtrl(uint8_t bit);
};

#endif